using System.Web.Profile;
using System.Configuration.Provider;
using System.Collections.Specialized;
using System;
using System.Data;
using System.Data.Odbc;
using System.Configuration;
using System.Diagnostics;
using System.Web;
using System.Collections;
using NET.Library.Data;

namespace NET.Library.Web.Security
{
    #region Tables
    /*

    This provider works with the following schema for the table of user data.

    CREATE TABLE Profiles
    (
      UniqueID AutoIncrement NOT NULL PRIMARY KEY,
      Username Text (255) NOT NULL,
      ApplicationName Text (255) NOT NULL,
      IsAnonymous YesNo, 
      LastActivityDate DateTime,
      LastUpdatedDate DateTime,
        CONSTRAINT PKProfiles UNIQUE (Username, ApplicationName)
    )

    CREATE TABLE StockSymbols
    (
      UniqueID Integer,
      StockSymbol Text (10),
        CONSTRAINT FKProfiles1 FOREIGN KEY (UniqueID)
          REFERENCES Profiles
    )

    CREATE TABLE ProfileData
    (
      UniqueID Integer,
      ZipCode Text (10),
        CONSTRAINT FKProfiles2 FOREIGN KEY (UniqueID)
          REFERENCES Profiles
    )

    */
    #endregion

    /// <summary>
    /// 
    /// </summary>
    public abstract class CustomProfileProvider : ProfileProvider
    {
        #region Fields
        //
        // Global connection string, generic exception message, event log info.
        //

        //private string _EventSource = "CustomProfileProvider";
        //private string _EventLog = "Application";
        //private string _ExceptionMessage = "An exception occurred. Please check the event log.";

        private string _ApplicationName;

        //
        // If false, exceptions are thrown to the caller. If true,
        // exceptions are written to the event log.
        //

        private bool _WriteExceptionsToEventLog;
        #endregion

        #region Properties
        /// <summary>
        /// 
        /// </summary>
        public bool WriteExceptionsToEventLog
        {
            get { return _WriteExceptionsToEventLog; }
            set { _WriteExceptionsToEventLog = value; }
        }

        /// <summary>
        /// System.Configuration.SettingsProvider.ApplicationName
        /// </summary>    
        public override string ApplicationName
        {
            get { return _ApplicationName; }
            set { _ApplicationName = value; }
        }

        #endregion

        /// <summary>
        /// System.Configuration.Provider.ProviderBase.Initialize Method 
        /// </summary>
        /// <param name="name"></param>
        /// <param name="config"></param>
        public override void Initialize(string name, NameValueCollection config)
        {

            //
            // Initialize values from web.config.
            //

            if (config == null)
                throw new ArgumentNullException("config");

            if (name == null || name.Length == 0)
                name = "CustomProfileProvider";

            if (String.IsNullOrEmpty(config["description"]))
            {
                config.Remove("description");
                config.Add("description", "Custom Data Profile provider");
            }

            // Initialize the abstract base class.
            base.Initialize(name, config);


            if (config["applicationName"] == null || config["applicationName"].Trim() == "")
            {
                _ApplicationName = System.Web.Hosting.HostingEnvironment.ApplicationVirtualPath;
            }
            else
            {
                _ApplicationName = config["applicationName"];
            }


            //
            // Initialize connection string.
            //

            //ConnectionStringSettings pConnectionStringSettings = ConfigurationManager.
            //    ConnectionStrings[config["connectionStringName"]];

            //if (pConnectionStringSettings == null ||
            //    pConnectionStringSettings.ConnectionString.Trim() == "")
            //{
            //    throw new ProviderException("Connection string cannot be blank.");
            //}

            // connectionString = pConnectionStringSettings.ConnectionString;
        }





        //
        // System.Configuration.SettingsProvider methods.
        //

        //
        // SettingsProvider.GetPropertyValues
        //

        //public override SettingsPropertyValueCollection
        //      GetPropertyValues(SettingsContext context,
        //            SettingsPropertyCollection ppc)
        //{
        //    string username = (string)context["UserName"];
        //    bool isAuthenticated = (bool)context["IsAuthenticated"];

        //    // The serializeAs attribute is ignored in this provider implementation.

        //    SettingsPropertyValueCollection svc =
        //        new SettingsPropertyValueCollection();

        //    foreach (SettingsProperty prop in ppc)
        //    {
        //        SettingsPropertyValue pv = new SettingsPropertyValue(prop);

        //        switch (prop.Name)
        //        {
        //            case "StockSymbols":
        //                pv.PropertyValue = GetStockSymbols(username, isAuthenticated);
        //                break;
        //            case "ZipCode":
        //                pv.PropertyValue = GetZipCode(username, isAuthenticated);
        //                break;
        //            default:
        //                throw new ProviderException("Unsupported property.");
        //        }

        //        svc.Add(pv);
        //    }

        //    UpdateActivityDates(username, isAuthenticated, true);

        //    return svc;
        //}



        //
        // SettingsProvider.SetPropertyValues
        //

        //public override void SetPropertyValues(SettingsContext context,
        //               SettingsPropertyValueCollection ppvc)
        //{
        //    // The serializeAs attribute is ignored in this provider implementation.

        //    string username = (string)context["UserName"];
        //    bool isAuthenticated = (bool)context["IsAuthenticated"];
        //    int uniqueID = GetUniqueID(username, isAuthenticated, false);
        //    if (uniqueID == 0)
        //        uniqueID = CreateProfileForUser(username, isAuthenticated);

        //    foreach (SettingsPropertyValue pv in ppvc)
        //    {
        //        switch (pv.Property.Name)
        //        {
        //            case "StockSymbols":
        //                SetStockSymbols(uniqueID, (ArrayList)pv.PropertyValue);
        //                break;
        //            case "ZipCode":
        //                SetZipCode(uniqueID, (string)pv.PropertyValue);
        //                break;
        //            default:
        //                throw new ProviderException("Unsupported property.");
        //        }
        //    }

        //    UpdateActivityDates(username, isAuthenticated, false);
        //}


        


        

        ////
        //// GetZipCode
        //// Retrieves ZipCode value from the database during 
        //// the call to GetPropertyValues.
        ////

        //private string GetZipCode(string username, bool isAuthenticated)
        //{
        //    string zipCode = "";

        //    OdbcConnection conn = new OdbcConnection(connectionString);
        //    OdbcCommand cmd = new OdbcCommand("SELECT ZipCode FROM Profiles " +
        //          "INNER JOIN ProfileData ON Profiles.UniqueID = ProfileData.UniqueID " +
        //          "WHERE Username = ? AND ApplicationName = ? And IsAnonymous = ?", conn);
        //    cmd.Parameters.Add("@Username", OdbcType.VarChar, 255).Value = username;
        //    cmd.Parameters.Add("@ApplicationName", OdbcType.VarChar, 255).Value = ApplicationName;
        //    cmd.Parameters.Add("@IsAnonymous", OdbcType.Bit).Value = !isAuthenticated;

        //    try
        //    {
        //        conn.Open();

        //        zipCode = (string)cmd.ExecuteScalar();
        //    }
        //    catch (OdbcException e)
        //    {
        //        if (WriteExceptionsToEventLog)
        //        {
        //            WriteToEventLog(e, "GetZipCode");
        //            throw new ProviderException(exceptionMessage);
        //        }
        //        else
        //        {
        //            throw e;
        //        }
        //    }
        //    finally
        //    {
        //        conn.Close();
        //    }

        //    return zipCode;
        //}

        ////
        //// SetZipCode
        //// Inserts the zip code value into the database during 
        //// the call to SetPropertyValues.
        ////

        //private void SetZipCode(int uniqueID, string zipCode)
        //{
        //    if (zipCode == null) { zipCode = String.Empty; }

        //    OdbcConnection conn = new OdbcConnection(connectionString);
        //    OdbcCommand cmd = new OdbcCommand("DELETE FROM ProfileData WHERE UniqueID = ?", conn);
        //    cmd.Parameters.Add("@UniqueID", OdbcType.Int).Value = uniqueID;

        //    OdbcCommand cmd2 = new OdbcCommand("INSERT INTO ProfileData (UniqueID, ZipCode) " +
        //               "Values(?, ?)", conn);
        //    cmd2.Parameters.Add("@UniqueID", OdbcType.Int).Value = uniqueID;
        //    cmd2.Parameters.Add("@ZipCode", OdbcType.VarChar, 10).Value = zipCode;

        //    OdbcTransaction tran = null;

        //    try
        //    {
        //        conn.Open();
        //        tran = conn.BeginTransaction();
        //        cmd.Transaction = tran;
        //        cmd2.Transaction = tran;

        //        // Delete any existing values.
        //        cmd.ExecuteNonQuery();
        //        cmd2.ExecuteNonQuery();

        //        tran.Commit();
        //    }
        //    catch (OdbcException e)
        //    {
        //        try
        //        {
        //            tran.Rollback();
        //        }
        //        catch
        //        {
        //        }

        //        if (WriteExceptionsToEventLog)
        //        {
        //            WriteToEventLog(e, "SetZipCode");
        //            throw new ProviderException(exceptionMessage);
        //        }
        //        else
        //        {
        //            throw e;
        //        }
        //    }
        //    finally
        //    {
        //        conn.Close();
        //    }
        //}


        


        //
        // ProfileProvider.DeleteProfiles(ProfileInfoCollection)
        //

        


        






        




    }

}